package com.wrx.service.generatesql;

import com.wrx.constants.generatesql.ConstantsCovert;
import com.wrx.dto.generatesql.*;
import jakarta.servlet.http.HttpServletResponse;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import net.sourceforge.pinyin4j.PinyinHelper;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.wrx.constants.generatesql.Constants.*;

@Slf4j
@Service
public class GenerateService {

    /**
     * 生成点位sql
     * @param dto
     * @param response
     */
    public void pointInsertSql(GeneratePointSql dto, HttpServletResponse response) {
        // 请求字符串 解析 点位数据集合
        List<String> pointLineList = convertPointLineList(dto.getConcatSql());
        // 点位数据集合 转换 INSERT SQL语句
        String resultSql = convertPointLineListToResultSql(dto, pointLineList);
        // 设置响应内容类型和下载文件名
        downLoadTxt(response, resultSql);
    }


    private String convertPointLineListToResultSql(GeneratePointSql requestParam,List<String> pointLineList) {
        // 点位sql模板
        String startSql = INSERT_SQL_PREFIX + requestParam.getDataBaseName() + POINT_SQL_TABLE_FIELD;
        String endSql = POINT_SQL_COMMON_VALUE + requestParam.getTenantId() + INSERT_SQL_SUFFIX;
        Integer startId = requestParam.getStartId();
        String iotDeviceId = requestParam.getIotDeviceId();
        StringBuilder resultSql = new StringBuilder();
        for (String pointLineData : pointLineList) {
            // 添加id
            resultSql.append(startSql).append(startId++).append(",");
            // 单位转换 并添加sql value语句的格式
            for (String part : unitConvertArr(pointLineData,iotDeviceId)) {
                if (StringUtils.isEmpty(part)) continue;
                if (part.equals("NULL")){
                    resultSql.append(part).append(",");
                } else{
                    resultSql.append("'").append(part).append("',");
                }
            }
            resultSql.append(endSql).append("\r\n");
        }
        return resultSql.toString();
    }


    /**
     * 解析请求参数点位字符串 为 点位数据集合
     */
    private List<String> convertPointLineList(String requestData) {
        // 点位sql模版固定每2个为一行数据
        List<String> requestLineData = Arrays.asList(requestData.split("\\s+"));
        StringBuilder pointLine = new StringBuilder();
        ArrayList<String> pointLineList = new ArrayList<>();
        int x = 1;
        for (int i = 0; i < requestLineData.size(); i++) {
            if(x%2 == 0){
                pointLine.append(requestLineData.get(i));
                pointLineList.add(pointLine.toString());
                pointLine = new StringBuilder();
            } else {
                pointLine.append(requestLineData.get(i)).append(" ");
            }
            x++;
        }
        return pointLineList;
    }

    /**
     * 老板本 待删除
     */
//    private String generatePointInsertSql(String value, Integer startId,String dataBaseName, Integer tenantId) {
//        // todo 这里改造成每四个分割成一行就不需要rn分割了
//        List<String> data = Arrays.asList(value.split("\\s+"));
//        ArrayList<String> pointList = new ArrayList<>();
//        StringBuilder pointLine = new StringBuilder();
//        int x = 1;
//        for (int i = 0; i < data.size(); i++) {
//            if(x%4 == 0){
//                pointLine.append(data.get(i));
//                pointList.add(pointLine.toString());
//                pointLine = new StringBuilder();
//            } else {
//                pointLine.append(data.get(i)).append(" ");
//            }
//            x++;
//        }
//        // 点位sql模板
//        String startSql = INSERT_SQL_PREFIX + dataBaseName + POINT_SQL_TABLE_FIELD;
//        String endSql = POINT_SQL_COMMON_VALUE + tenantId + INSERT_SQL_SUFFIX;
//        // 创建一个StringBuilder来构建所需的格式
//        StringBuilder formattedStr = new StringBuilder();
//        for (String pointLineData : pointList) {
//            // 添加id
//            formattedStr.append(startSql).append(startId++).append(",");
//            // 单位转换 并添加sql value语句的格式
//            for (String part : unitConvertArr(pointLineData)) {
//                if (StringUtils.isEmpty(part)) continue;
//                if (part.equals("NULL")){
//                    formattedStr.append(part).append(",");
//                } else{
//                    formattedStr.append("'").append(part).append("',");
//                }
//            }
//            formattedStr.append(endSql).append("\r\n");
//        }
//        return formattedStr.toString();
//    }

    private static final Map<List<String>, String> POINT_UNIT_MAPPING = new LinkedHashMap<>();

    static {
        POINT_UNIT_MAPPING.put(Arrays.asList("压力"), "MPa");
        POINT_UNIT_MAPPING.put(Arrays.asList("电流"), "A");
        POINT_UNIT_MAPPING.put(Arrays.asList("温度"), "℃");
        POINT_UNIT_MAPPING.put(Arrays.asList("频率"), "Hz");
        POINT_UNIT_MAPPING.put(Arrays.asList("功率"), "kW");
        POINT_UNIT_MAPPING.put(Arrays.asList("能耗", "电能", "电量"), "kW·h");
        POINT_UNIT_MAPPING.put(Arrays.asList("浊度"), "NTU");
        POINT_UNIT_MAPPING.put(Arrays.asList("瞬时流量", "流量"), "m³/h");
        POINT_UNIT_MAPPING.put(Arrays.asList("累计流量", "水量"), "m³");
        POINT_UNIT_MAPPING.put(Arrays.asList("余氯"), "mg/L");
        POINT_UNIT_MAPPING.put(Arrays.asList("速度", "液位"), "m");
        POINT_UNIT_MAPPING.put(Arrays.asList("速度给定"), "L/h");
        POINT_UNIT_MAPPING.put(Arrays.asList("流速"), "m/s");
        POINT_UNIT_MAPPING.put(Arrays.asList("电导率"), "μS/cm");
        POINT_UNIT_MAPPING.put(Arrays.asList("电压"), "V");
    }


    private List<String> unitConvertArr(String lineData,String iotDeviceId) {
        // 匹配格式1 字符串 中文 数字 字符串
//        Pattern pattern = Pattern.compile("^(\\S+)\\s+(.*?)\\s+(\\d+)\\s+(\\S+)$");
        // 匹配格式2 字符串 中文 字符串 数字
//        Pattern pattern = Pattern.compile("^(\\S+)\\s+(.*?)\\s+(\\S+)\\s+(\\S+)$");
        // 匹配格式3 字符串 中文
        Pattern pattern = Pattern.compile("^(\\S+)\\s+(.*?)$");
        List<String> lineDataList = new ArrayList<>();
        Matcher matcher = pattern.matcher(lineData.trim());
        if (matcher.find()) {
            // 提取4个字段
            String code = matcher.group(1);        // 例如 GL_JYJ_METERB_AX_DY
            String pointName = matcher.group(2);   // 例如 加药间电表_A相_电压
//            String id = matcher.group(3);          // 例如 1907275327614812162
//            String codeRepeat = matcher.group(4);  // 例如 GL_JYJ_METERB_AX_DY
            // 判断单位
            String unit = "NULL";
            for (Map.Entry<List<String>, String> entry : POINT_UNIT_MAPPING.entrySet()) {
                for (String keyword : entry.getKey()) {
                    if (pointName.contains(keyword)) {
                        unit = entry.getValue();
                    }
                }
            }
            // 构造最终list（5个字段）
            lineDataList = Arrays.asList(code, pointName, unit, iotDeviceId, code);
        } else {
            System.out.println("格式不符合预期: " + lineData);
        }
        return lineDataList;
    }


    /**
     * 生成设备点位sql
     * @param dto
     * @param response
     */
    public void devicePointInsertSql(DeviceAndDevicePointDto dto, HttpServletResponse response) {
        String content = generateDevicePointInsetSqlEasyAll(dto);
        // 设置响应内容类型和下载文件名
        downLoadTxt(response, content);
    }

    private String generateDevicePointInsetSqlEasyAll(DeviceAndDevicePointDto dto) {
        // 公共字段
        Integer deviceId = dto.getDeviceId();
        Integer deviceIdCopy = dto.getDeviceId();
        Integer devicePointId = dto.getDevicePointId();
        Integer factoryId = dto.getFactoryId();
        String partSql = dto.getPartSql();
        String dataBaseName = dto.getDataBaseName();
        Integer tenantId = dto.getTenantId();
        // 设备sql模板
        String deviceStartSql = INSERT_SQL_PREFIX + dataBaseName+DEVICE_SQL_TABLE_FIELD;
        String deviceEndSql = DEVICE_SQL_COMMON_VALUE+tenantId+INSERT_SQL_SUFFIX;
        // 设备点位sql模板
        String devicePointStartSql = INSERT_SQL_PREFIX +dataBaseName+DEVICE_POINT_SQL_TABLE_FIELD;
        String devicePointEndSql = DEVICE_POINT_SQL_COMMON_VALUE+tenantId+INSERT_SQL_SUFFIX;
        // 创建一个StringBuilder来构建sql
        StringBuilder resultSql = new StringBuilder();
        // 存放设备数据
        List<String> deviceNameList = new ArrayList<>();
        // 存放设备点位数据
        Map<Integer,List<String>> devicePointMap = new HashMap<>();

        // 源数据 筛选 设备和设备点位数据 deviceNameList devicePointMap
        filterDeviceNameAndDevicePoint(partSql, devicePointMap, deviceIdCopy, deviceNameList);

        // 生成设备sql
        generateDeviceSql(resultSql, deviceNameList, deviceStartSql, deviceId, factoryId, deviceEndSql);

        // 生成设备点位sql
        generateDevicePointSql(resultSql, devicePointMap, devicePointStartSql, devicePointId, devicePointEndSql);
        return resultSql.toString();
    }

    /**
     * 生成设备点位sql
     */
    private void generateDevicePointSql(StringBuilder resultSql, Map<Integer, List<String>> devicePointMap, String devicePointStartSql, Integer devicePointId, String devicePointEndSql) {
        resultSql.append("\r\n").append("\r\n").append("# 设备点位sql\r\n");
        for (Map.Entry<Integer, List<String>> entry : devicePointMap.entrySet()) {
            Integer deviceCopyId = entry.getKey();
            for (String lineData : entry.getValue()) {
                // 拼接sql
                resultSql.append(devicePointStartSql).append(devicePointId++).append(",").append(deviceCopyId).append(",");
                // 处理设备点位的状态和开关
                String lineDataBuilder = convertStatusAndControlTypeMethod(lineData);
                // 处理sql中value符号 NULL不处理，中文需要添加 ''
                for (String part : lineDataBuilder.split("\\s+")) {
                    if (StringUtils.isEmpty(part)) continue;
                    resultSql.append(part.equals("NULL") ? part : "'" + part + "'")
                            .append(",");
                }
                resultSql.append(devicePointEndSql).append("\r\n");
            }
        }
    }

    private static void generateDeviceSql(StringBuilder resultSql, List<String> deviceNameList, String deviceStartSql, Integer deviceId, Integer factoryId, String deviceEndSql) {
        resultSql.append("# 设备sql\r\n");
        for (String deviceData : deviceNameList) {
            String[] split = deviceData.split("_");
            String deviceName = split[0];
            String deviceGroupName = null;
            String deviceGroupCode;
            if(split.length>1){
                deviceGroupName = split[1];
            }
            if (StringUtils.isEmpty(deviceGroupName)) {
                deviceGroupName = "送水泵房";
                deviceGroupCode = "SSBF";
            } else {
                char[] chars = deviceGroupName.toCharArray();
                StringBuilder deviceGroupCodeBuilder = new StringBuilder();
                for (int i = 0; i < chars.length; i++) {
                    char ch = chars[i];
                    // 默认转首字母拼音
                    String[] pinyins = PinyinHelper.toHanyuPinyinStringArray(ch);
                    if (pinyins != null && pinyins.length > 0) {
                        deviceGroupCodeBuilder.append(Character.toUpperCase(pinyins[0].charAt(0)));
                    } else {
                        deviceGroupCodeBuilder.append(ch);
                    }
                }
                deviceGroupCode = deviceGroupCodeBuilder.toString();
            }
            String deviceEndSqlReplace = deviceEndSql.replace("送水泵房", deviceGroupName).replace("SSBF", deviceGroupCode);
            resultSql.append(deviceStartSql)
                    .append(deviceId++).append(",").append(factoryId).append(",")
                    .append("'").append(deviceName).append("',")
                    .append(deviceEndSqlReplace)
                    .append("\r\n");
        }
    }

    private static void filterDeviceNameAndDevicePoint(String partSql, Map<Integer, List<String>> devicePointMap, Integer deviceIdCopy, List<String> deviceNameList) {
        String prevEnglish = null;
        Boolean isFirst = true;
        for (String line : partSql.split("\\s+")) {
            line = line.trim();
            if (line.isEmpty()) continue;
            // 如果是纯英文行，暂存，准备组合
            if (line.matches("^[A-Za-z0-9_]+$")) {
                prevEnglish = line;
                continue;
            }
            // 如果是中文行，并且有英文暂存，拼成属性
            if (prevEnglish != null) {
                List<String> devicePointList = devicePointMap.get(deviceIdCopy);
                if (devicePointList == null) { devicePointList = new ArrayList<>(); }
                devicePointList.add(prevEnglish + " " + line);
                devicePointMap.put(deviceIdCopy,devicePointList);
                prevEnglish = null;
            } else {
                // 没有英文在前，说明是一个设备名或组名
                deviceNameList.add(line);
                if(isFirst){
                    isFirst = false;
                } else {
                    deviceIdCopy++;
                }
            }
        }
    }

    private void downLoadTxt(HttpServletResponse response, String content) {
        response.setContentType("text/plain; charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment; filename=\"output.txt\"");
        try (PrintWriter writer = response.getWriter()) {
            writer.write(content);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static final Map<List<String>, String> STATUS_MAPPING = new LinkedHashMap<>();

    static {
        // 状态类型映射
        STATUS_MAPPING.put(Arrays.asList("远程"), " REMOTE NULL");
        STATUS_MAPPING.put(Arrays.asList("故障"), " FAILURE NULL");
        STATUS_MAPPING.put(Arrays.asList("开到位"), " SWITCH_ON NULL");
        STATUS_MAPPING.put(Arrays.asList("关到位", "阀关控制"), " SWITCH_OFF NULL");
        STATUS_MAPPING.put(Arrays.asList("手自动"), " AUTO NULL");
        STATUS_MAPPING.put(Arrays.asList("运行"), " RUN NULL");
        // 控制类型映射
        STATUS_MAPPING.put(Arrays.asList("手动", "上位关阀", "上位开阀", "close", "open", "stop", "设置", "启动"),
                " CONTROL {\"0\":\"停止\",\"1\":\"启动\"}");
        STATUS_MAPPING.put(Arrays.asList("切换模式"),
                " CONTROL {\"0\":\"工频模式\",\"1\":\"变频模式\"}");
        STATUS_MAPPING.put(Arrays.asList("投入"),
                " CONTROL {\"0\":\"未投入\",\"1\":\"投入\"}");
        STATUS_MAPPING.put(Arrays.asList("阀-开", "阀-关", "开阀", "关阀", "停阀"),
                " CONTROL {\"0\":\"不点动\",\"1\":\"点动\"}");
    }

    /**
     * 处理设备点位的状态和开关
     * 备用匹配规则
     * Pattern pattern = Pattern.compile("^(\\S+)\\s+(.*?)\\s+(\\S+)\\s+(\\S+)$");
     * 备用设备点位名称字段
     * String[] devicePointData = lineData.split("\\s+");
     * String devicePointName = devicePointData[1];
     */
    private String convertStatusAndControlTypeMethod(String lineData) {
        StringBuilder lineDataBuilder = new StringBuilder();
        // 转换状态和开关
        String statusTypeAndValue = convertStatusAndControlTypeValue(lineData);
        lineDataBuilder.append(lineData).append(statusTypeAndValue);
        return lineDataBuilder.toString();
    }

    /**
     * 处理设备点位的状态和开关值
     */
    private static String convertStatusAndControlTypeValue(String lineData) {
        for (Map.Entry<List<String>, String> entry : STATUS_MAPPING.entrySet()) {
            for (String keyword : entry.getKey()) {
                if (lineData.contains(keyword)) {
                    return entry.getValue();
                }
            }
        }
        // 默认DATA类型  没有匹配到状态和开关则为DATA类型
        return " DATA NULL";
    }

    /**
     * 转换状态
     */
    private static String convertStatusType(String lineData, String statusTypeAndValue) {
        if (lineData.contains("远程")){
            statusTypeAndValue = " REMOTE NULL";
        } else if (lineData.contains("故障")){
            statusTypeAndValue = " FAILURE NULL";
        } else if ( lineData.contains("开到位")){
            statusTypeAndValue = " SWITCH_ON NULL";
        } else if ( lineData.contains("关到位") || lineData.contains("阀关控制")){
            statusTypeAndValue = " SWITCH_OFF NULL";
        } else if (lineData.contains("手自动")){
            statusTypeAndValue = " AUTO NULL";
        }  else if (lineData.contains("运行")){
            statusTypeAndValue = " RUN NULL";
        }
        return statusTypeAndValue;
    }

    /**
     * 转换开关
     */
    private String convertControlStatusType(String lineData, String statusTypeAndValue){
        if (lineData.contains("手动") || lineData.contains("上位关阀") || lineData.contains("上位开阀")
                || lineData.contains("close") || lineData.contains("open") || lineData.contains("stop")
                || lineData.contains("设置") || lineData.contains("启动") ){
            statusTypeAndValue = " CONTROL {\"0\":\"停止\",\"1\":\"启动\"}";
        } else if (lineData.contains("切换模式") ){
            statusTypeAndValue = " CONTROL {\"0\":\"工频模式\",\"1\":\"变频模式\"}";
        }

        else if (lineData.contains("投入") ){
            statusTypeAndValue = " CONTROL {\"0\":\"未投入\",\"1\":\"投入\"}";
        } else if (lineData.contains("阀-开") || lineData.contains("阀-关") || lineData.contains("阀开")
                || lineData.contains("阀关") || lineData.contains("阀停")){
            statusTypeAndValue = " CONTROL {\"0\":\"不点动\",\"1\":\"点动\"}";
        }

        //        else if (lineData.contains("手自动") ){
//            lineDataBuilder.append(" CONTROL {\"0\":\"自动\",\"1\":\"手动\"}");
//        }
        return statusTypeAndValue;
    }

    public void generatePointAndDevicePointSql(GeneratePointAndDevicePointSql dto, HttpServletResponse response) {
        HashMap<String, String> tableDataMaps = regexDataToMap(dto.getConcatSql());
        // 生成点位SQL
        StringBuilder pointSql = generatePointSql(tableDataMaps.get("point"), dto);
        // 设备数据
        List<String> deviceNameList = new ArrayList<>();
        // 设备点位数据
        Map<Integer,List<String>> devicePointMap = new HashMap<>();
        // 筛选设备和设备点位数据以及点位数据 todo 优化 分开设备和设备点位生成 一个表一个方法
        makePointAndDevicePointList(tableDataMaps.get("deviceAndDevicePoint"), devicePointMap, dto.getDeviceId(), deviceNameList);
        // 生成设备sql
        StringBuilder deviceBuilder = generateDeviceSql(deviceNameList, dto);
        // 生成设备点位sql
        StringBuilder devicePointBuilder = generateDevicePointSql(devicePointMap, dto);
        //
        // 合并sql
        String resultBuilder = pointSql + "\r\n" +
                deviceBuilder + "\r\n" +
                devicePointBuilder;
        // 设置响应内容类型和下载文件名
        downLoadTxt(response, resultBuilder);
    }



    private StringBuilder generatePointSql(String pointData,GeneratePointAndDevicePointSql dto){
        // 解析 点位数据
        List<String> pointLineList = convertPointLineList(pointData);
        // 生成 点位INSERT_SQL
        return convertPointInsertSql(dto, pointLineList);
    }

    /**
     * 通过正则匹配请求字符串 转换为 对应类型的字符串放在map中
     * 如 point 对应是point的字符串
     * device 对应是device的字符串
     */
    private HashMap<String, String> regexDataToMap(String params) {
        HashMap<String, String> result = new HashMap<>();
        Pattern pattern = Pattern.compile(
                "(point|deviceAndDevicePoint|config)\\s+(.*?)(?=point|deviceAndDevicePoint|config|$)",
                Pattern.DOTALL
        );
        Matcher matcher = pattern.matcher(params);
        while (matcher.find()) {
            String type = matcher.group(1);
            String content = matcher.group(2).trim();
            result.put(type, content);
        }
        return result;
    }

    private StringBuilder convertPointInsertSql(GeneratePointAndDevicePointSql requestParam,List<String> pointLineList) {
        // 点位sql模板
        String startSql = INSERT_SQL_PREFIX + requestParam.getDataBaseName() + POINT_SQL_TABLE_FIELD;
        String endSql = POINT_SQL_COMMON_VALUE + requestParam.getTenantId() + INSERT_SQL_SUFFIX;
        Integer startId = requestParam.getStartId();
        String iotDeviceId = requestParam.getIotDeviceId();
        StringBuilder resultSql = new StringBuilder();
        resultSql.append("# 点位sql\r\n");
        for (String pointLineData : pointLineList) {
            // 添加id
            resultSql.append(startSql).append(startId++).append(",");
            // 单位转换 并添加sql value语句的格式
            for (String part : unitConvertArr(pointLineData,iotDeviceId)) {
                if (StringUtils.isEmpty(part)) continue;
                if (part.equals("NULL")){
                    resultSql.append(part).append(",");
                } else{
                    resultSql.append("'").append(part).append("',");
                }
            }
            resultSql.append(endSql).append("\r\n");
        }
        return resultSql;
    }

    /**
     * 生成设备点位sql
     */
    private StringBuilder generateDevicePointSql( Map<Integer, List<String>> devicePointMap,GeneratePointAndDevicePointSql dto) {
        StringBuilder resultSql = new StringBuilder();
        Integer devicePointId = dto.getDevicePointId();
        // 设备点位sql模板
        String devicePointStartSql = INSERT_SQL_PREFIX +dto.getDataBaseName()+DEVICE_POINT_SQL_TABLE_FIELD;
        String devicePointEndSql = DEVICE_POINT_SQL_COMMON_VALUE+dto.getTenantId()+INSERT_SQL_SUFFIX;
        resultSql.append("\r\n").append("\r\n").append("# 设备点位sql\r\n");
        for (Map.Entry<Integer, List<String>> entry : devicePointMap.entrySet()) {
            Integer deviceCopyId = entry.getKey();
            for (String lineData : entry.getValue()) {
                // 拼接sql
                resultSql.append(devicePointStartSql).append(devicePointId++).append(",").append(deviceCopyId).append(",");
                // 处理设备点位的状态和开关
                String lineDataBuilder = convertStatusAndControlTypeMethod(lineData);
                // 处理sql中value符号 NULL不处理，中文需要添加 ''
                for (String part : lineDataBuilder.split("\\s+")) {
                    if (StringUtils.isEmpty(part)) continue;
                    resultSql.append(part.equals("NULL") ? part : "'" + part + "'")
                            .append(",");
                }
                resultSql.append(devicePointEndSql).append("\r\n");
            }
        }
        return resultSql;
    }


    private static StringBuilder generateDeviceSql(List<String> deviceNameList, GeneratePointAndDevicePointSql dto) {
        StringBuilder resultSql = new StringBuilder();
        Integer deviceId = dto.getDeviceId();
        // 设备sql模板
        String deviceStartSql = INSERT_SQL_PREFIX + dto.getDataBaseName()+DEVICE_SQL_TABLE_FIELD;
        String deviceEndSql = DEVICE_SQL_COMMON_VALUE+dto.getTenantId()+INSERT_SQL_SUFFIX;
        resultSql.append("# 设备sql\r\n");
        for (String deviceData : deviceNameList) {
            String[] split = deviceData.split("_");
            String deviceName = split[0];
            String deviceGroupName = null;
            String deviceGroupCode;
            if(split.length>1){
                deviceGroupName = split[1];
            }
            if (StringUtils.isEmpty(deviceGroupName)) {
                deviceGroupName = "送水泵房";
                deviceGroupCode = "SSBF";
            } else {
                char[] chars = deviceGroupName.toCharArray();
                StringBuilder deviceGroupCodeBuilder = new StringBuilder();
                for (int i = 0; i < chars.length; i++) {
                    char ch = chars[i];
                    // 默认转首字母拼音
                    String[] pinyins = PinyinHelper.toHanyuPinyinStringArray(ch);
                    if (pinyins != null && pinyins.length > 0) {
                        deviceGroupCodeBuilder.append(Character.toUpperCase(pinyins[0].charAt(0)));
                    } else {
                        deviceGroupCodeBuilder.append(ch);
                    }
                }
                deviceGroupCode = deviceGroupCodeBuilder.toString();
            }
            String deviceEndSqlReplace = deviceEndSql.replace("送水泵房", deviceGroupName).replace("SSBF", deviceGroupCode);
            resultSql.append(deviceStartSql)
                    .append(deviceId++).append(",").append(dto.getFactoryId()).append(",")
                    .append("'").append(deviceName).append("',")
                    .append(deviceEndSqlReplace)
                    .append("\r\n");
        }
        return resultSql;
    }

    private static void convertDeviceList(String data, Map<Integer, List<String>> devicePointMap, Integer deviceIdCopy, List<String> deviceNameList, List<String> pointLineList) {
        if(data != null){
            String prevEnglish = null;
            Boolean isFirst = true;
            for (String line : data.split("\\s+")) {
                line = line.trim();
                if (line.isEmpty()) continue;
                // 如果是纯英文行，暂存，准备组合
                if (line.matches("^[A-Za-z0-9_]+$")) {
                    prevEnglish = line;
                    continue;
                }
                // 没有英文在前，说明是连续的中文 则判断为设备名
                if (prevEnglish == null) {
                    deviceNameList.add(line);
                }
            }
        }
    }
    private static void makePointAndDevicePointList(String data, Map<Integer, List<String>> devicePointMap, Integer deviceIdCopy, List<String> deviceNameList) {
        if(data != null){
            String prevEnglish = null;
            Boolean isFirst = true;
            for (String line : data.split("\\s+")) {
                line = line.trim();
                if (line.isEmpty()) continue;
                // 如果是纯英文行，暂存，准备组合
                if (line.matches("^[A-Za-z0-9_]+$")) {
                    prevEnglish = line;
                    continue;
                }
                // 如果是中文行，并且有英文暂存，拼成属性
                if (prevEnglish != null) {
                    List<String> devicePointList = devicePointMap.get(deviceIdCopy);
                    if (devicePointList == null) { devicePointList = new ArrayList<>(); }
                    // 添加到设备点位数据
                    devicePointList.add(prevEnglish + " " + line);
                    devicePointMap.put(deviceIdCopy,devicePointList);
                    prevEnglish = null;
                } else {
                    // 没有英文在前，说明是一个设备名或组名
                    deviceNameList.add(line);
                    if(isFirst){
                        isFirst = false;
                    } else {
                        deviceIdCopy++;
                    }
                }
            }
        }
    }




    /**
     */
    @SneakyThrows
    public String generateTotalInsertSqlByFile(InputStream inputStream, GenerateTotalInsertSqlByFileDto dto, HttpServletResponse response) {
        // 解析文件 转换对应实体类集合
        PointRelatedDOList allDoListResult = getAllDoListResult(inputStream, dto);
        // 转换点位单位 并生成点位Insert Sql
        StringBuilder pointInsertSql = convertPointInsertSql(dto.getDataBaseName(),dto.getTenantId(), convertPointUnit(allDoListResult.getPointList()));
        // 生成设备Insert Sql
        StringBuilder deviceInsertSql = convertDeviceInsertSql(dto, allDoListResult.getDeviceList());
        // 转换设备点位数据类型和类型值 并生成点位Insert Sql
        StringBuilder devicePointInsertSql = convertDevicePointInsertSql(dto, convertDevicePointTypeAndTypeValue(allDoListResult.getDevicePointList()));
        // 合并sql
        String resultBuilder = pointInsertSql + "\r\n"
                + deviceInsertSql + "\r\n"
                +devicePointInsertSql;
        return resultBuilder.toString();
        // 设置响应内容类型和下载文件名
//        downLoadTxt(response, resultBuilder);
    }


    private static PointRelatedDOList getAllDoListResult(InputStream inputStream, GenerateTotalInsertSqlByFileDto dto) throws IOException {
        AtomicInteger pointId = new AtomicInteger(dto.getPointId());
        AtomicInteger deviceId = new AtomicInteger(dto.getDeviceId());
        AtomicInteger devicePointId = new AtomicInteger(dto.getDevicePointId());
        Integer factoryId = dto.getFactoryId();

        List<PointDO> pointDOList = new ArrayList<>();
        List<DeviceDO> deviceDOList = new ArrayList<>();
        List<DevicePointDO> devicePointDOList = new ArrayList<>();

        String line;
        boolean isPointSection = false;
        boolean isDeviceSection = false;
        DeviceDO currentDevice = null;
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
        while ((line = reader.readLine()) != null) {
            line = line.trim();
            if (line.isEmpty()) continue;
            if ("point".equalsIgnoreCase(line)) {
                isPointSection = true;
                continue;
            }
            if ("deviceAndDevicePoint".equalsIgnoreCase(line)) {
                isDeviceSection = true;
                isPointSection = false;
                continue;
            }
            // ----------- 处理 point 部分 -----------
            if (isPointSection) {
                addPointDOList(dto, line, pointId, pointDOList);
            }

            // ----------- 处理 device 部分 -----------
            else if (isDeviceSection) {
                String[] parts = line.split("\\s+");
                // 如果只有一个元素，则认为是设备名
                if(parts.length == 1) {
                    currentDevice = new DeviceDO();
                    currentDevice.setId(deviceId.incrementAndGet());
                    currentDevice.setDeviceName(line);
                    currentDevice.setFactoryId((long) factoryId); // dto.getFactoryId()
                    String[] split = line.split("unit");
                    if (split.length == 2) {
                        currentDevice.setDeviceName(split[0]);
                        currentDevice.setLocation(split[1]);
                        // 转换首拼
                        char[] chars = currentDevice.getLocation().toCharArray();
                        StringBuilder unitCodeBuilder = new StringBuilder();
                        for (int i = 0; i < chars.length; i++) {
                            char ch = chars[i];
                            // 默认转首字母拼音
                            String[] pinyins = PinyinHelper.toHanyuPinyinStringArray(ch);
                            if (pinyins != null && pinyins.length > 0) {
                                unitCodeBuilder.append(Character.toUpperCase(pinyins[0].charAt(0)));
                            } else {
                                unitCodeBuilder.append(ch);
                            }
                        }
                        currentDevice.setUnitCode(unitCodeBuilder.toString());
                    }
                    deviceDOList.add(currentDevice);
                } else {
                    addDevicePointDOList(line, currentDevice, devicePointId, deviceId, devicePointDOList);
                }
            }
        }
        return new PointRelatedDOList(pointDOList, deviceDOList, devicePointDOList);
    }

    private static void addDeviceDOList(String line, DeviceDO currentDevice, AtomicInteger devicePointId, AtomicInteger deviceId, List<DevicePointDO> devicePointDOList) {
    }

    private static void addDevicePointDOList(String line, DeviceDO currentDevice, AtomicInteger devicePointId, AtomicInteger deviceId, List<DevicePointDO> devicePointDOList) {
        // 是设备点位
        String[] parts2 = line.split("\\s+");
        if (parts2.length >= 2 && currentDevice != null) {
            DevicePointDO dp = new DevicePointDO();
            dp.setId(devicePointId.incrementAndGet());
            dp.setDeviceId(deviceId.get());
            dp.setPointCode(parts2[0].trim());
            dp.setPointShowName(parts2[1].trim());
            devicePointDOList.add(dp);
        }
    }

    private static void addPointDOList(GenerateTotalInsertSqlByFileDto dto, String line, AtomicInteger pointId, List<PointDO> pointDOList) {
        String[] parts = line.split("\\s+");
        if (parts.length >= 2) {
            PointDO point = new PointDO();
            point.setId(pointId.incrementAndGet());
            point.setPointCode(parts[0].trim());
            point.setPointName(parts[1].trim());
            point.setIotDeviceId(dto.getIotDeviceId());
            String iotPointId = parts.length == 3 ? parts[2] : parts[0];
            point.setIotPointId(iotPointId);
            pointDOList.add(point);
        }
    }


    private List<PointDO> convertPointUnit(List<PointDO> pointList) {
        for (PointDO pointDO : pointList) {
            String pointName = pointDO.getPointName();
            String pointUnit = pointDO.getPointUnit();
            // 转换当前点位的单位
            for (Map.Entry<List<String>, String> entry : POINT_UNIT_MAPPING.entrySet()) {
                for (String keyword : entry.getKey()) {
                    if (pointName.contains(keyword)) {
                        pointUnit = entry.getValue();
                    }
                }
            }
            pointDO.setPointUnit(pointUnit);
        }
        return pointList;
    }

    private StringBuilder convertPointInsertSql(String dataBaseName, Integer tenantId,List<PointDO> pointDOList) {
        // 点位sql模板
        String startSql = INSERT_SQL_PREFIX + dataBaseName + POINT_SQL_TABLE_FIELD;
        String endSql = POINT_SQL_COMMON_VALUE + tenantId + INSERT_SQL_SUFFIX;
        StringBuilder resultSql = new StringBuilder();
        resultSql.append("# 点位sql\r\n");
        for (PointDO pointDO : pointDOList) {
            // 拼接sql
            resultSql.append(startSql);
            resultSql.append(String.format("%d, '%s', '%s',%s,'%s','%s',",
                    pointDO.getId(),
                    pointDO.getPointCode(),
                    pointDO.getPointName(),
                    pointDO.getPointUnit() == null ? "NULL" : "'" + pointDO.getPointUnit() + "'",
                    pointDO.getIotDeviceId(),
                    pointDO.getIotPointId()
            ));
            resultSql.append(endSql).append("\r\n");
        }
        return resultSql;
    }


    private StringBuilder convertDeviceInsertSql(GenerateTotalInsertSqlByFileDto dto,List<DeviceDO> deviceDOList) {
        // 设备sql模板
        String deviceStartSql = INSERT_SQL_PREFIX + dto.getDataBaseName()+DEVICE_SQL_TABLE_FIELD;
        String deviceEndSql = DEVICE_SQL_COMMON_VALUE_V2+dto.getTenantId()+INSERT_SQL_SUFFIX;
        StringBuilder resultSql = new StringBuilder();
        resultSql.append("# 设备sql\r\n");
        for (DeviceDO deviceDO : deviceDOList) {
            // 拼接sql
            resultSql.append(deviceStartSql);
            resultSql.append(String.format("%d, %d, '%s',%s,%s,",
                    deviceDO.getId(),
                    deviceDO.getFactoryId(),
                    deviceDO.getDeviceName(),
                    deviceDO.getUnitCode() == null ? "NULL" : "'" + deviceDO.getUnitCode() + "'",
                    deviceDO.getLocation() == null ? "NULL" : "'" + deviceDO.getLocation() + "'"
            ));
            resultSql.append(deviceEndSql).append("\r\n");
        }
        return resultSql;
    }
    private StringBuilder convertDevicePointInsertSql(GenerateTotalInsertSqlByFileDto dto,List<DevicePointDO> devicePointDOList) {
        // 设备点位sql模板
        String devicePointStartSql = INSERT_SQL_PREFIX +dto.getDataBaseName()+DEVICE_POINT_SQL_TABLE_FIELD;
        String devicePointEndSql = DEVICE_POINT_SQL_COMMON_VALUE+dto.getTenantId()+INSERT_SQL_SUFFIX;
        StringBuilder resultSql = new StringBuilder();
        resultSql.append("# 设备点位sql\r\n");
        for (DevicePointDO devicePointDO : devicePointDOList) {
            resultSql.append(devicePointStartSql);
            if (devicePointDO.getStatusValue() == null) {
                System.out.println();
            }
            resultSql.append(String.format("%d, %d, '%s','%s','%s',%s,",
                    devicePointDO.getId(),
                    devicePointDO.getDeviceId(),
                    devicePointDO.getPointCode(),
                    devicePointDO.getPointShowName(),
                    devicePointDO.getStatusType(),
                    devicePointDO.getStatusValue() == null ? "NULL" : "'" + devicePointDO.getStatusValue() + "'"
            ));
            resultSql.append(devicePointEndSql).append("\r\n");
        }
        return resultSql;
    }

    private List<DevicePointDO> convertDevicePointTypeAndTypeValue(List<DevicePointDO> devicePointDOList) {
        for (DevicePointDO devicePointDO : devicePointDOList) {
            String pointShowName = devicePointDO.getPointShowName();
            for (Map.Entry<List<String>, String> entry : STATUS_MAPPING.entrySet()) {
                for (String keyword : entry.getKey()) {
                    if (pointShowName.contains(keyword)) {
                        String[] statusTypeAndValue = entry.getValue().trim().split("\\s+");
                        devicePointDO.setStatusType(statusTypeAndValue[0]);
                        devicePointDO.setStatusValue(!statusTypeAndValue[1].equals("NULL") ? statusTypeAndValue[1] : null);
                    }
                }
            }
            // 默认DATA类型  没有匹配到状态和开关则为DATA类型
            devicePointDO.setStatusType(devicePointDO.getStatusType() != null ? devicePointDO.getStatusType() : "DATA");
        }
        return devicePointDOList;
    }

    /**
     * 模板
     * WS2_YZPNF1_SZD                    一组排泥阀1_手自动
     * WS2_YZPNF1_GDW                    一组排泥阀1_关到位
     * WS2_JLPUMP_1_SDQT                    计量泵_1_手动启停
     * WS2_JLPUMP_2_SDQT                    计量泵_2_手动启停
     * WS2_PNJ_SZD                    排泥机_手自动
     * WS2_CCS_LL                    出厂水_流量
     * WS2_QQ_1_ND                    氢气_1_浓度
     * WS2_QSPUMP_SZD                    取水泵_手自动
     * 在原文件基础上 筛选跟设备有关的点位追加在后面 并生成新的文件
     * 结果
     * deviceAndDevicePoint
     * WS2_YZPNF1_SZD                    一组排泥阀1_手自动
     * WS2_YZPNF1_GDW                    一组排泥阀1_关到位
     * WS2_JLPUMP_1_SDQT                    计量泵_1_手动启
     * WS2_JLPUMP_2_SDQT                    计量泵_2_手动启
     * WS2_PNJ_SZD                    排泥机_手自动
     * WS2_QSPUMP_SZD                    取水泵_手自动
     * @param file
     * @param response
     */
    /**
     * 增加设备点位（支持 InputStream，用于 Swing）
     * @param inputStream 输入流
     * @return 转换后的结果字符串
     */
    @SneakyThrows
    public String addDevicePointByInputStream(InputStream inputStream) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
        StringBuilder pointBuilder = new StringBuilder();
        pointBuilder.append("point\r\n");
        StringBuilder deviceAndDevicePointBuilder = new StringBuilder();
        deviceAndDevicePointBuilder.append("deviceAndDevicePoint\r\n");
        StringBuilder resultBuilder = new StringBuilder();

        // 区分点位中的设备点位
        ArrayList<DevicePointDO> devicePointDOList = getDevicePointDOList(reader, pointBuilder);

        // 分组
        Map<String, List<DevicePointDO>> grouped = devicePointDOList.stream()
                .collect(Collectors.groupingBy(d -> extractDeviceName(d.getPointShowName())));

        // 拼接字符串
        grouped.forEach((device, points) -> {
            deviceAndDevicePointBuilder.append(device).append("\n");
            for (DevicePointDO dp : points) {
                deviceAndDevicePointBuilder.append(dp.getPointCode())
                        .append("    ") // 这里可以调整间隔
                        .append(dp.getPointShowName())
                        .append("\r\n");
            }
        });

        resultBuilder.append(pointBuilder).append(deviceAndDevicePointBuilder);
        return resultBuilder.toString();
    }

    private static ArrayList<DevicePointDO> getDevicePointDOList(BufferedReader reader, StringBuilder pointBuilder) throws IOException {
        String line;
        ArrayList<DevicePointDO> devicePointDOList = new ArrayList<>();
        // 区分哪些点位是设备点位相关的
        while ((line = reader.readLine()) != null) {
            line = line.trim();
            pointBuilder.append(line).append("\r\n");
            String[] parts = line.split("\\s+");
            if (parts.length >= 2) {
                for (Map.Entry<List<String>, Boolean> entry : ConstantsCovert.WORD_DEVICE_MAPPING.entrySet()) {
                    for (String keyword : entry.getKey()) {
                        if (parts[1].contains(keyword)) {
                            if (entry.getValue()){
                                DevicePointDO devicePointDO = new DevicePointDO();
                                devicePointDO.setPointCode(parts[0]);
                                devicePointDO.setPointShowName(parts[1]);
                                devicePointDOList.add(devicePointDO);
                            }
                            // 命中后就不再继续匹配，避免重复添加
                            break; // 跳出内层循环
                        }
                    }
                }
            }
        }
        return devicePointDOList;
    }

    // 提取设备名的方法
    private static String extractDeviceName(String showName) {
        // 如果是数字开头 或 数字结尾 直接走关键字逻辑
        if (!showName.isEmpty()
                && (Character.isDigit(showName.charAt(0)) || Character.isDigit(showName.charAt(showName.length() - 1)))) {
            String[] keywords = {"泵", "阀", "机"};
            for (String k : keywords) {
                int idx = showName.indexOf(k);
                if (idx != -1) {
                    return showName.substring(0, idx + 1); // 包含关键字
                }
            }
            return showName; // 没有关键字就返回原值
        }

        // 如果包含数字 就取最后一位数字之前的字符串
        if (!showName.isEmpty()
                && !Character.isDigit(showName.charAt(0))
                && showName.chars().anyMatch(Character::isDigit)) {

            int lastDigit = -1;
            for (int i = showName.length() - 1; i >= 0; i--) {
                if (Character.isDigit(showName.charAt(i))) {
                    lastDigit = i;
                    break;
                }
            }
            if (lastDigit != -1) {
                return showName.substring(0, lastDigit + 1); // 电磁阀_1_1组_联点控 -> 电磁阀_1_1
            }
        }


        // 其他情况，走关键字逻辑
        String[] keywords = {"泵", "阀", "机"};
        for (String k : keywords) {
            int idx = showName.indexOf(k);
            if (idx != -1) {
                return showName.substring(0, idx + 1);
            }
        }

        // 实在没匹配上，就整个返回
        return showName;
    }


    /**
     * 解析文件 一键生成  点位、监测点、监测点配置信息
     */
    public void generatePipeTotalInsertSqlByFile(MultipartFile file, GeneratePipeRelatedSqlReq req, HttpServletResponse response) {
        // 解析文件 转换对应实体类集合
        PipeRelatedDOList pipeRelatedDOList = getPipeRelatedDoList(file, req);
        // 转换点位单位 并生成点位Insert Sql
        StringBuilder pointInsertSql = convertPointInsertSql(req.getDataBaseName(),req.getTenantId(), convertPointUnit(pipeRelatedDOList.getPointList()));
        StringBuilder pipeInsertSql = convertPipeInsertSql(req.getDataBaseName(),req.getTenantId(), pipeRelatedDOList.getPipeDOList());
        StringBuilder pipeShowConfigInsertSql = convertPipeShowConfigInsertSql(req.getDataBaseName(),req.getTenantId(), pipeRelatedDOList.getPipeShowConfigDOList());
        // 合并sql
        String resultBuilder = pointInsertSql + "\r\n" + pipeInsertSql + "\r\n" + pipeShowConfigInsertSql;
        // 设置响应内容类型和下载文件名
        downLoadTxt(response, resultBuilder);

    }

    private StringBuilder convertPipeShowConfigInsertSql(String dataBaseName, Integer tenantId, List<PipeShowConfigDO> pipeShowConfigDOList) {
        // 点位sql模板
        String startSql = INSERT_SQL_PREFIX + dataBaseName + INSERT_PIPE_SHOW_CONFIG_FIELD;
        String endSql = INSERT_PIPE_SHOW_CONFIG_VALUE + tenantId + INSERT_SQL_SUFFIX;
        StringBuilder resultSql = new StringBuilder();
        resultSql.append("# 监测点展示配置sql\r\n");
        for (PipeShowConfigDO pipeShowConfigDO : pipeShowConfigDOList) {
            // 拼接sql
            resultSql.append(startSql);
            resultSql.append(String.format("%d, '%s', '%s', '%s', '%s',",
                    pipeShowConfigDO.getId(),
                    pipeShowConfigDO.getPipeId(),
                    pipeShowConfigDO.getDataType(),
                    pipeShowConfigDO.getPointCode(),
                    pipeShowConfigDO.getPointShowName()
            ));
            resultSql.append(endSql).append("\r\n");
        }
        return resultSql;
    }

    private StringBuilder convertPipeInsertSql(String dataBaseName, Integer tenantId, List<PipeDO> pipeDOList) {
        // 点位sql模板
        String startSql = INSERT_SQL_PREFIX + dataBaseName + INSERT_PIPE_FIELD;
        String endSql = INSERT_PIPE_VALUE + tenantId + INSERT_SQL_SUFFIX;
        StringBuilder resultSql = new StringBuilder();
        resultSql.append("# 监测点sql\r\n");
        for (PipeDO pipeDO : pipeDOList) {
            // 拼接sql
            resultSql.append(startSql);
            resultSql.append(String.format("%d, '%s', '%s',",
                    pipeDO.getId(),
                    pipeDO.getPipeName(),
                    "113.23062,36.344526"
            ));
            resultSql.append(endSql).append("\r\n");
        }
        return resultSql;
    }

    @SneakyThrows
    private PipeRelatedDOList getPipeRelatedDoList(MultipartFile file, GeneratePipeRelatedSqlReq dto) {
        AtomicInteger pointId = new AtomicInteger(dto.getPointId());
        AtomicInteger pipeId = new AtomicInteger(dto.getPipeId());
        AtomicInteger pipeShowConfigId = new AtomicInteger(dto.getPipeShowConfigId());

        List<PointDO> pointDOList = new ArrayList<>();
        List<PipeDO> pipeDOList = new ArrayList<>();
        List<PipeShowConfigDO> pipeShowConfigDOList = new ArrayList<>();

        String currentSection = "";
        String line;
        BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8));
        while ((line = reader.readLine()) != null) {
            line = line.trim();
            if (line.isEmpty()) continue;
            // ---------- 切换 section ----------
            currentSection = getCurrentSection(line, currentSection);
            if (currentSection == null) continue;

            // ----------- 处理 pipe 部分 -----------
            if ("pipe".equals(currentSection)) {
                addPipeDOList(line, pipeId, pipeDOList);
            // ----------- 处理 point 部分 -----------
            } else if ("point".equals(currentSection)) {
                addPointDOList(line, pipeDOList, pointId, pointDOList);
            }
            // ----------- 处理 pipeShowConfig 部分 -----------
            else if ("pipeShowConfig".equals(currentSection)) {
                addPipeShowConfigDOList(line, pipeDOList, pipeShowConfigId, pipeShowConfigDOList);
            }
        }
        return new PipeRelatedDOList(pointDOList, pipeDOList, pipeShowConfigDOList);
    }

    private void addPipeShowConfigDOList(String line, List<PipeDO> pipeDOList, AtomicInteger pipeShowConfigId, List<PipeShowConfigDO> pipeShowConfigDOList) {
        String[] parts = line.split("\\s+");
        if (parts.length >= 2) {
            int pipeCount = 1;
            for (PipeDO pipeDO : pipeDOList) {
                PipeShowConfigDO pipeShowConfigDO = new PipeShowConfigDO();
                pipeShowConfigDO.setId(pipeShowConfigId.incrementAndGet());
                pipeShowConfigDO.setPointCode(parts[0].trim()+pipeCount);
                pipeShowConfigDO.setPointShowName(parts[1].trim()+pipeCount);
                pipeShowConfigDO.setDataType(parts[2].trim());
                pipeShowConfigDO.setPipeId(pipeDO.getId());
                pipeShowConfigDOList.add(pipeShowConfigDO);
                pipeCount++;
            }
        }

    }

    private void addPointDOList(String line, List<PipeDO> pipeDOList, AtomicInteger pointId, List<PointDO> pointDOList) {
        String[] parts = line.split("\\s+");
        if (parts.length >= 2) {
            int pipeCount = 1;
            for (PipeDO pipeDO : pipeDOList) {
                PointDO point = new PointDO();
                point.setId(pointId.incrementAndGet());
                point.setPointCode(parts[0].trim()+pipeCount);
                point.setPointName(parts[1].trim()+pipeCount);
                point.setIotDeviceId(pipeDO.getIotDeviceId());
                point.setIotPointId(parts[0].trim());
                pointDOList.add(point);
                pipeCount++;
            }
        }
    }

    private void addPipeDOList(String line, AtomicInteger  pipeId, List<PipeDO> pipeDOList) {
        String[] parts = line.split("\\s+");
        PipeDO pipeDO = new PipeDO();
        pipeDO.setId(pipeId.incrementAndGet());
        pipeDO.setPipeName("监测点"+ pipeId);
        pipeDO.setIotDeviceId(parts[0].trim());
        pipeDOList.add(pipeDO);
    }

    private static String getCurrentSection(String line, String currentSection) {
        if ("point".equalsIgnoreCase(line)) {
            currentSection = "point";
        }
        if ("pipeShowConfig".equalsIgnoreCase(line)) {
            currentSection = "pipeShowConfig";
        }
        if ("pipe".equalsIgnoreCase(line)) {
            currentSection = "pipe";
        }
        return currentSection;
    }


    /**
     * 中文转英文首拼
     * @param response
     */
    @SneakyThrows
    public void chineseToEnglishByFile(MultipartFile file, String prefix, HttpServletResponse response) {
        String result = chineseToEnglishByInputStream(file.getInputStream(), prefix);
        downLoadTxt(response, result);
    }

    /**
     * 中文转英文首拼（支持 InputStream，用于 Swing）
     * @param inputStream 输入流
     * @param prefix 前缀
     * @return 转换后的结果字符串
     */
    @SneakyThrows
    public String chineseToEnglishByInputStream(InputStream inputStream, String prefix) {
        String line = "";
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
        StringBuilder sb = new StringBuilder();
        ArrayList<String> codeList = new ArrayList<>();
        while ((line = reader.readLine()) != null) {
            line = line.trim();
            if (line.isEmpty()) continue; // 跳过空行

            String[] split = line.split("\\s+");
            if (split.length < 2) continue; // 跳过格式不正确的行

            String codeName = split[0];
            String codeGroupName = split[1];
            String replaceCodeName = codeName;
            // 转换当前中文对应的英文
            for (Map.Entry<List<String>, String> entry : ConstantsCovert.WORD_MAPPING.entrySet()) {
                for (String keyword : entry.getKey()) {
                    if (replaceCodeName.contains(keyword)) {
                        replaceCodeName = replaceCodeName.replace(keyword, entry.getValue());
                    }
                }
            }
            StringBuilder code = new StringBuilder(prefix);
            char[] chars = replaceCodeName.toCharArray();
            // 默认转中文首字母拼音 改造查询ArrayList<String> codeList如果当前首拼重名了 则加上分组codeGroupName的首拼前缀
            for (int i = 0; i < chars.length; i++) {
                char ch = chars[i];
                String[] pinyins = PinyinHelper.toHanyuPinyinStringArray(ch);
                if (pinyins != null && pinyins.length > 0) {
                    code.append(Character.toUpperCase(pinyins[0].charAt(0)));
                } else {
                    code.append(ch);
                }
            }

            String finalCode = code.toString();
            // 如果首拼重复了，前面加上分组名首拼前缀
            if (codeList.contains(finalCode)) {
                StringBuilder groupPrefix = new StringBuilder();
                char[] groupChars = codeGroupName.toCharArray();
                for (char ch : groupChars) {
                    String[] pinyins = PinyinHelper.toHanyuPinyinStringArray(ch);
                    if (pinyins != null && pinyins.length > 0) {
                        groupPrefix.append(Character.toUpperCase(pinyins[0].charAt(0)));
                    } else {
                        groupPrefix.append(ch);
                    }
                }
                finalCode = prefix + groupPrefix + "_"+ code.substring(prefix.length());
            }
            // 添加对应中文以及换行
            sb.append(finalCode).append("                    ").append(codeName).append("\r\n");
            codeList.add(finalCode);
        }

        return sb.toString();
    }
}
